package cc.messcat.util;

import java.io.File;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

import cc.messcat.common.util.ContainerUtil;
import cc.messcat.common.util.ExcelHandler;
import cc.messcat.common.util.StringUtil;
import jxl.Cell;
import jxl.Sheet;
import jxl.Workbook;

public class PoorVillageControllerExcelHandler extends ExcelHandler {

	/**
	 * 从Excel文件里读取数据保存到Map里
	 * 
	 * @param fileName
	 *            Excel文件的名称
	 * @return Map 数据文件，类型是Map<List<Object>>，每个map是一个sheet，
	 *         sheet包含list，list的泛型类型是一个Object，利用反射机制设置值
	 */

	// 村属性
	static final List<String> natureList = Arrays.asList("贫困村", "非贫困村", "经济薄弱村", "十二五贫困村", "十三五贫困村");
	// 不可以为空的列
	static final List<String> isNotCellList = Arrays.asList("2", "3", "4", "5", "8", "9", "10", "11", "22", "24", "25");
	static StringBuffer errInfo = new StringBuffer();

	// 储存 行政区划编码，行列
	static Map<String, String> codeMap = new HashMap<String, String>();

	@SuppressWarnings("unchecked")
	public static Map readExcel(String fileName, List<String> areaList) throws Exception {
		Map data = new HashMap();
		String err = null;
		String packageName = "cc.messcat.entity.fupin.";
		Workbook book = Workbook.getWorkbook(new File(fileName));
		String[] sheetNames = book.getSheetNames();
		// 判断是否为多表
		if (sheetNames!=null && sheetNames.length>1) {
			err = "excel文档不能存在多表";
			data.put("errInfo", err);
			return data;
		}
		int rows = 0;
		for (int i = 0; i < sheetNames.length; i++) {

			// sheet的名称就是JavaBean的类名
			String sheetName = sheetNames[i];
			String className = packageName + "PoorVillage";

			// 获取sheet
			Sheet sheet = book.getSheet(sheetName);
			rows = sheet.getRows();
			// 判断是否为空
			if (rows == 0) {
				err = "excel文档为空";
				data.put("errInfo", err);
				return data;
			}
			// 判断行数
			if (rows > 120000) {
				err = "excel文档行数不能大于两万";
				data.put("errInfo", err);
				return data;
			}

			// 表头的列序号与JavaBean属性名称的映射Map
			Map columnFieldName = new HashMap();

			// 循环行
			List dataList = new ArrayList();
			for (int rowIndex = 0; rowIndex < rows; rowIndex++) {

				// 获取行，一行包含N列，也就是Cell的数组
				Cell[] cell = sheet.getRow(rowIndex);
				//判断excel文档表头数量
			/*	if (cell!=null && cell.length  <25) {
					err = "excel文档表头列数有误";
					data.put("errInfo", err);
					return data;
				}*/
				

				// 约定第一行是表头，也就是JavaBean的属性名称，保存进columnFieldName

				if (rowIndex == 2) {
					for (int cellIndex = 1; cellIndex < cell.length; cellIndex++) {
						if (cellIndex > 24 && StringUtils.isBlank( cell[cellIndex].getContents())) break;
						String temp;
						/*
						 * if(cell[cellIndex].getContents().equals("序号")){//
						 * temp = "serialNum"; }else
						 */ if (cell[cellIndex].getContents().equals("行政区划编码")) {//
							temp = "code";
						} else if (cell[cellIndex].getContents().equals("县")) {//
							temp = "cty";
						} else if (cell[cellIndex].getContents().equals("乡（镇）")) {
							temp = "cry";
						} else if (cell[cellIndex].getContents().equals("村")) {
							temp = "name";// village
						} else if (cell[cellIndex].getContents().equals("负责人")) {
							temp = "fpeople";
						} else if (cell[cellIndex].getContents().equals("村办公电话")) {
							temp = "contact";
						} else if (cell[cellIndex].getContents().equals("村属性")) {
							temp = "nature";
						} else if (cell[cellIndex].getContents().equals("是否出列")) {
							temp = "type";// 是否出列字段：默认0:贫困村 1：转为自然村 2:被删除
						} else if (cell[cellIndex].getContents().equals("总户数")) {
							temp = "total";
						} else if (cell[cellIndex].getContents().equals("总人口数")) {
							temp = "totalNumber";
						} else if (cell[cellIndex].getContents().equals("自然村数")) {
							temp = "natlNumber";
						} else if (cell[cellIndex].getContents().equals("贫困户数")) {
							temp = "poor";
						} else if (cell[cellIndex].getContents().equals("贫困人口数")) {
							temp = "poorNumber";
						} else if (cell[cellIndex].getContents().equals("低保人口数")) {
							temp = "lowNumber";
						} else if (cell[cellIndex].getContents().equals("低保户数")) {
							temp = "lowHouse";
						} else if (cell[cellIndex].getContents().equals("五保人口数")) {
							temp = "fiveNumber";
						} else if (cell[cellIndex].getContents().equals("五保户数")) {
							temp = "fiveHouse";
						} else if (cell[cellIndex].getContents().equals("少数民族人口数")) {
							temp = "lessNumber";
						} else if (cell[cellIndex].getContents().equals("妇女人口数")) {
							temp = "womanNumber";
						} else if (cell[cellIndex].getContents().equals("残疾人口数")) {
							temp = "remnantNumber";
						} else if (cell[cellIndex].getContents().equals("劳动力人数")) {
							temp = "labourNumber";
						} else if (cell[cellIndex].getContents().equals("外出务工人数")) {
							temp = "gooutNumber";
						} else if (cell[cellIndex].getContents().equals("省")) {
							temp = "province";
						} else if (cell[cellIndex].getContents().equals("市（州）")) {
							temp = "city";
						} else {
							temp = cell[cellIndex].getContents();
							err = "excel文档表头格式有误[" + (rowIndex+1) + "行" + (char) ('@' + (cellIndex+1)) + "列]";
							data.put("errInfo", err);
							return data;
						}

						columnFieldName.put(cellIndex, temp);
					}
				}

				// 从第二行开始循环数据
				else if (rowIndex != 0 && rowIndex != 1) {

					// 类名前面已经含有包名，就可以使用class获取该JavaBean的实例
					Object javaBean = Class.forName(className).newInstance();

					// 循环每列数据并set进JavaBean的属性里
					for (int cellIndex = 1; cellIndex < cell.length; cellIndex++) {

						// 格子里的值
						String value = cell[cellIndex].getContents();

						// 户数和人口数为空时，默认按0来处理。
						if (cellIndex + 1 >= 10 && cellIndex + 1 <= 23) {
							value = StringUtil.isBlank(value) ? "0" : value;
						}

						// 校验数据
						err = gainVerification(value, rowIndex + 1, cellIndex + 1, areaList);

						// 按照列的序号获取表头的列名或JavaBean的属性名称
						String fieldName = (String) columnFieldName.get(cellIndex);

						// 拿到JavaBean里某属性的setter方法名称
						System.out.println(fieldName);
						String setter=null;
						try {
							 setter = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
							
						} catch (Exception e) {
							if(StringUtil.isNotBlank(err)){
								data.put("errInfo", err);
								errInfo.setLength(0);
								codeMap.clear();
								book.close();
								return data;
							}
						}
					
						Method[] method0 = javaBean.getClass().getMethods();
						Class[] methodParaClass = null;

						// 循环找到setter里参数的类型
						for (int k = 0; k < method0.length; k++) {
							if (setter.equals(method0[k].getName())) {
								methodParaClass = method0[k].getParameterTypes();
								break;
							}
						}
						Method method = javaBean.getClass().getMethod(setter, methodParaClass);
						String methodParaClassName = methodParaClass[0].getName();

						// 如果参数类型是JavaBean类型，则设置JavaBean的id值即可
						if (getClassType(methodParaClassName) == 3) {
							if (StringUtil.isNotBlank(value) && !"null".equals(value)) {

								// 设置JavaBean的id值
								Object innerJavaBean = methodParaClass[0].newInstance();
								Method method1 = innerJavaBean.getClass().getMethod("setId", Long.class);
								method1.invoke(innerJavaBean, new Object[] { Long.parseLong(value) });

								// 再设置JavaBean对象到宿主JavaBean
								method.invoke(javaBean, new Object[] { innerJavaBean });
							}
						} else {

							// 从格子里拿到的值都是String，现在根据不同类型要转换为不同类型的值，并set进JavaBean里
							Object paraVal = getValueByClassType(methodParaClassName, value);
							method.invoke(javaBean, new Object[] { paraVal });
						}
					}

					// 一个JavaBean设置值完成后则保存进list里

					dataList.add(javaBean);
				}
			}

			// 一个sheet循环完后则保存进data里
			data.put(sheetName, dataList);
		}

		data.put("errInfo", err);
		errInfo.delete(0, errInfo.length());
		codeMap.clear();
		book.close();
		return data;
	}

	/**
	 * 校验方法
	 * 
	 * @param value
	 *            值
	 * @param rowIndex
	 *            行
	 * @param cellIndex
	 *            列
	 * @param areaList
	 *            查找村管理中的信息 必输项为空  * 通过行政区划编码查找村管理中的信息时，查询不到对应的信息；  *
	 *            村属性列的录入的信息与提供的字典信息不一致。
	 *
	 * 
	 * @return
	 */
	private static String gainVerification(String value, int rowIndex, int cellIndex, List<String> areaList) {
		// 为空判断
		if (isNotCellList.contains(String.valueOf(cellIndex))) {
			if (StringUtil.isBlank(value)) {
				rowIndexCell(rowIndex, cellIndex).append("必输项为空<br/>");
			}
		}
		// 行政区划编码
		if (cellIndex == 2 && StringUtil.isNotBlank(value)) {
			if (!areaList.contains(value)) {
				rowIndexCell(rowIndex, cellIndex).append("行政区划编码查找村管理中的信息时，查询不到对应的信息<br/>");
			}
			// 导入的行政区划编码列中，不能相同
			if (codeMap.containsKey(value)) {
				rowIndexCell(rowIndex, cellIndex).append(codeMap.get(value) + "行政区划编码相同<br/>");
			} else {
				// 储存 证件号码，行列
				codeMap.put(value, rowIndex + "行" + (char) ('@' + cellIndex) + "列");
			}
		}

		// 村属性
		if (cellIndex == 8) {
			if (StringUtil.isNotBlank(value) && !natureList.contains(value)) {
				rowIndexCell(rowIndex, cellIndex).append("录入的信息与提供的字典信息不一致<br/>");
			}
		}
		return errInfo.toString();
	}

	public static StringBuffer rowIndexCell(int rowIndex, int cellIndex) {
		return errInfo.append(rowIndex).append("行").append((char) ('@' + cellIndex)).append("列,");
	}

}
